home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
progutil
/
stdwin.zoo
/
atari
/
trees.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-30
|
4KB
|
219 lines
#include <stdio.h>
#include <assert.h>
#include <aesbind.h>
#include <vdibind.h>
#ifdef __GNUC__
#include <gemfast.h>
#else
#include <obdefs.h>
#include <gemdefs.h>
#endif
#include "l_defs.h"
#include "window.h"
#include "trees.h"
#include "atari_proto.h"
#undef P
#define bool int
#define TRUE 1
#define FALSE 0
#define NEXT(i) t->obj[i].ob_next
#define HEAD(i) t->obj[i].ob_head
#define TAIL(i) t->obj[i].ob_tail
/* Move the focus to the root node of the tree.
Return TRUE if the tree isn't empty. */
bool
tr_root(t)
TREE *t;
{
t->focus= 0;
return t->nobjs > 0;
}
/* Move the focus to its parent.
Return TRUE if not already at the root. */
bool
tr_parent(t)
TREE *t;
{
int old;
if (t->focus == 0)
return FALSE;
do {
old= t->focus;
t->focus= NEXT(t->focus);
assert(t->focus >= 0 && t->focus < t->nobjs);
} while (TAIL(t->focus) != old);
return TRUE;
}
/* Move the focus to its sibling.
Return TRUE if not already at the last sibling. */
bool
tr_sibling(t)
TREE *t;
{
int new;
if (t->nobjs <= 0)
return FALSE;
new= NEXT(t->focus);
if (TAIL(new) == t->focus)
return FALSE;
t->focus= new;
return TRUE;
}
/* Move the focus to the first child.
Return FALSE if no children. */
bool
tr_child(t)
TREE *t;
{
int new= HEAD(t->focus);
if (new < 0)
return FALSE;
t->focus= new;
return TRUE;
}
/* Return the number of children of the current node.
Return -1 if the tree is empty.
Warning: this may loop infinitely if the tree is malformed. */
int
tr_nchildren(t)
TREE *t;
{
int i= t->focus;
int hd;
int n= 0;
if (i >= t->nobjs)
return -1;
if ((hd= HEAD(i)) < 0)
return 0;
while (hd != i)
++n, hd= NEXT(hd);
return n;
}
/* Add a new node to the tree.
If 'as_child' is TRUE, it is a new child of the current node;
otherwise, it is its sibling. */
OBJECT *
tr_add(t, as_child, type, flags, state, spec, x, y, width, height)
TREE *t;
int as_child;
int type, flags, state;
long spec;
int x, y, width, height;
{
int new;
OBJECT *o;
L_EXTEND(t->nobjs, t->obj, OBJECT, 1);
if (t->obj == NULL)
return NULL;
new= t->nobjs - 1;
if (new == 0) { /* Creating the root */
NEXT(new)= -1;
}
else if (as_child) { /* Add as first child of focus */
assert(HEAD(t->focus) < 0); /* Must be first */
HEAD(t->focus)= TAIL(t->focus)= new;
NEXT(new)= t->focus;
}
else { /* Add as sibling of focus */
assert(TAIL(NEXT(t->focus)) == t->focus); /* Must be last */
NEXT(new)= NEXT(t->focus);
NEXT(t->focus)= new;
TAIL(NEXT(new))= new;
}
HEAD(new)= TAIL(new)= -1;
t->focus= new;
o= &t->obj[new];
o->ob_type= type;
o->ob_flags= flags;
o->ob_state= state;
o->ob_spec= spec;
o->ob_x= x;
o->ob_y= y;
o->ob_width= width;
o->ob_height= height;
return o;
}
/* Print a dump of a tree. */
void
tr_dump(t)
TREE *t;
{
FILE *fp ;
int i= 0;
int level= 0;
if ((fp = fopen ("tree.dmp", "w")) == NULL)
wdebug ("Cannot open dump file") ;
if (t->nobjs <= 0) {
fprintf(fp, "Empty tree.\n");
return;
}
do {
int k;
fprintf(fp, "%d.", i);
for (k= 0; k < level; ++k)
fprintf(fp, " ");
fprintf (fp, " %d, %d, %d, %d", t->obj[i].ob_x, t->obj[i].ob_y,
t->obj[i].ob_width, t->obj[i].ob_height) ;
if (t->obj[i].ob_type == G_TITLE || t->obj[i].ob_type == G_STRING)
fprintf (fp, " %s\n", t->obj[i].ob_spec) ;
else
fprintf (fp, "\n") ;
if (HEAD(i) >= 0) {
++level;
i= HEAD(i);
}
else {
while (NEXT(i) >= 0 && TAIL(NEXT(i)) == i) {
--level;
i= NEXT(i);
}
i= NEXT(i);
}
} while (i >= 0);
fclose (fp) ;
}
OBJECT *
tr_node(t)
TREE *t;
{
if (t->nobjs <= 0)
return NULL;
return &t->obj[t->focus];
}
OBJECT *
tr_tree(t)
TREE *t;
{
if (t->nobjs <= 0)
return NULL;
t->obj[t->nobjs - 1].ob_flags |= LASTOB;
return t->obj;
}